/*******************************************************************
*
*    DESCRIPTION:delete unused rules once a minute
*
*    AUTHOR:
*
*    HISTORY:
*
*    DATE:9/3/2006
*
*******************************************************************/
#include "head.h"
#include "config.h"
#include "iptables.h"
#include "rulescleaner.h"
//glbal
int delete_sport[MAX_SPORT];
int delete_rules_counter = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

/*
 *Function Name:GetTcpSportFromConntrack
 *
 *Parameters:
 *
 *Description:Read /proc/net/ip_conntrack to find out which sport is open
 *
 *Returns:
 *
 */

int GetTcpSportFromConntrack(int tcp_sport[], int size)
{

	FILE *fp;
	int i = 0;
	char buffer[256];
	char csport[10];
	char cprotocol[5];
	//we must load conn_track module first,we have done this in IptablesInitByXml()
	fp = fopen("/proc/net/ip_conntrack", "r");
	assert(fp != NULL);
	while ( fgets(buffer, 255, fp) != NULL )
	{
		memset(csport, 0, 10);
		memset(cprotocol, 0, 5);
		strncpy(cprotocol, buffer, 3);
		if ( strcmp(cprotocol, "tcp") == 0 )
		{
			char *psport = strstr(buffer, "sport");
			assert(psport != NULL);
			strncpy(csport, psport + 6, 5);
			if ( i < size )
			{

				tcp_sport[i] = atoi(csport);
				i ++;
			}
			else
			{
				printf("In GetTcpSportFromConntrack:too much tcp link\n");
				return i;
			}
		}
		else
		{
			continue;
		}
		return i;
	}

	fclose(fp);
}
/*
 *Function Name:IsStillAlive
 *
 *Parameters:
 *
 *Description:
 *
 *Returns:
 *
 */
int IsStillAlive(int sport, int tcp_sport[], int n)
{
	int i;
	for ( i = 0; i < n; i++ )
	{
		if ( sport == tcp_sport[i] )
		{
			return 1;
		}
	}
	return 0;
}
/*
 *Function Name:RulesCleaner
 *
 *Parameters:
 *
 *Description:clean unused rules once a minute
 *OutputMonitor thread is used to add rules and 
 *this one is used to delete rules
 *
 *Returns:
 *
 */

void* RulesCleaner(void *data)
{
#ifdef _DEBUG
	printf("Enter RulesCleaner\n");
#endif
	int i, j;
	pthread_detach(pthread_self());
	int tcp_sport[MAX_SPORT];
	while ( 1 )
	{
		//check once a SLEEP_TIME
		sleep(SLEEP_TIME);

#ifdef _DEBUG
		printf("RulesCleaner wakeup");
#endif
		int sport_counter = GetTcpSportFromConntrack(tcp_sport, MAX_SPORT);
		//lock mutex
		pthread_mutex_lock(&mutex);
		for ( i =0; i < delete_rules_counter; i++ )
		{
			if ( IsStillAlive(delete_sport[i], tcp_sport, sport_counter) )
			{
				continue;
			}
			else
			{
				IptablesDeleteSportRules(delete_sport[i]);
			}
		}

		delete_rules_counter = 0;//flush counter
		pthread_mutex_unlock(&mutex);
	}
}

